package com.pactera.jep.service.sys.web.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.pactera.jep.autoconfigure.web.controller.BaseRestController;
import com.pactera.jep.commons.CollectionUtils;
import com.pactera.jep.orm.Filter;
import com.pactera.jep.orm.Operator;
import com.pactera.jep.orm.Order;
import com.pactera.jep.orm.Page;
import com.pactera.jep.service.sys.dto.UnitDto;
import com.pactera.jep.service.sys.service.UserProfileService;
import com.pactera.jep.sys.code.StaffStatus;
import com.pactera.jep.sys.dto.StaffDto;
import com.pactera.jep.sys.model.*;
import com.pactera.jep.sys.service.*;
import com.pactera.jep.web.code.WebCode;
import com.pactera.jep.web.code.WebHeaderCode;
import com.pactera.jep.web.entity.BasicNameValuePair;
import com.pactera.jep.web.entity.NameValuePair;
import com.pactera.jep.web.util.RequestUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Api(value = "用户")
@RestController
@RequestMapping("/staff")
public class StaffRestController extends BaseRestController<Staff> {

    private static final Logger LOG = LoggerFactory.getLogger(StaffRestController.class);

    @Autowired
    private StaffService staffService;

    @Autowired
    StaffGroupService staffGroupService;

    @Autowired
    DutyService dutyService;

    @Autowired
    StaffGroupMapService staffGroupMapService;

    @Autowired
    UnitService unitService;

    @Autowired
    StaffRoleGroupMapService staffRoleGroupMapService;

    @Autowired
    RoleService roleService;

    @Autowired
    RoleGroupService roleGroupService;

    @Autowired
    UserService userService;

    @Autowired
    BizDeptStaffService bizDeptStaffService;

    @Autowired
    UserProfileService userLoginService;

    /**
     * 为列表页面做数据准备
     */
    @Override
    protected void prepareQuery(String token, Page<Staff> page, List<Filter> filters, List<Order> orders, HttpServletRequest request) {
        staffService.query(page, filters, orders);
    }

    @ApiOperation(value = "获取当前机构的所有用户数据。包含用户角色信息，角色组信息，用户组信息")
    @GetMapping(value = {"/queryByUnitCode"})
    public Map<String, Object> queryByUnitCode (@RequestParam(value = "unitCode" ,required=false) String unitCode, Page<StaffDto> page, HttpServletRequest request){
        Map<String, Object> result = new HashMap<String, Object>();

        List<Filter> filters = RequestUtils.buildFilters(request);
        filters.add(new Filter("status", StaffStatus.ENABLE.getValue()));

        List<Order> orders = RequestUtils.buildOrders(request);
        orders.add(new Order("staffCode"));

        Page<StaffDto> list = staffService.queryByUnitCode(unitCode, page, filters, orders);

        result.put(RESULT_TOTAL, page.getTotal());
        result.put(RESULT_ROWS, page.getResult());
        return result;
    }

    @ApiOperation(value = "获得所有列表数据")
    @GetMapping(value = {"/queryAllOfDept"}, produces = {"application/json;charset=UTF-8"})
    public Map<String, Object> query(@ApiIgnore @RequestHeader(WebHeaderCode.X_USER_TOKEN) String token, Page<StaffDto> page, HttpServletRequest request)
    {
        Map<String, Object> result = new HashMap<String, Object>();
        List<Filter> filters = RequestUtils.buildFilters(request);
        List<Order> orders = RequestUtils.buildOrders(request);

        Page<StaffDto> list = staffService.selectStaffDto(page, filters, orders);
        for (StaffDto staff : list.getResult()) {
            String roleCode = combineRoleCode(staff.getStaffCode());
            staff.setRoleCode(roleCode);
            String roleName = combineRoleName(staff.getStaffCode());
            staff.setRoleName(roleName);
            String roleGroupCode = combineRoleGroupCode(staff.getStaffCode());
            staff.setRoleGroupCode(roleGroupCode);
            String roleGroupName = combineRoleGroupName(staff.getStaffCode());
            staff.setRoleGroupName(roleGroupName);
            String staffGroupCode = combineStaffGroupCode(staff.getStaffCode());
            staff.setStaffGroupCode(staffGroupCode);
            String staffGroupName = combineStaffGroupName(staff.getStaffCode());
            staff.setStaffGroupName(staffGroupName);
        }

        result.put(RESULT_TOTAL, page.getTotal());
        result.put(RESULT_ROWS, page.getResult());
        return result;
    }

    @ApiOperation(value = "获得所有列表数据")
    @PostMapping(value = {"/selectStaffByPositions"})
    public String selectStaffByPositions(@RequestParam("positions") String positions){
        Set<String> positionsList = new HashSet<>();
        String[] strs = null;
        if(StringUtils.isNotBlank(positions)){
            strs = positions.split(",");
            for(String str:strs){
                positionsList.add(str);
            }
        }

        String staffsString = null;
        List<Staff> staffs =   staffService.selectStaffByPositions(positionsList);
        if(CollectionUtils.isNotEmpty(staffs)){
            staffsString = JSONArray.toJSON(staffs).toString();
        }
        return staffsString;
    }

    @ApiOperation(value = "获得所有列表数据")
    @PostMapping(value = {"/selectStaff4Positions"})
    public String selectStaff4Positions(@RequestParam("positions") String positions){
        Set<String> positionsList = new HashSet<>();
        String[] strs = null;
        if(StringUtils.isNotBlank(positions)){
            strs = positions.split(",");
            for(String str:strs){
                positionsList.add(str);
            }
        }
        String staffsString = null;
        List<Staff> staffs = staffService.selectStaffByPositions(positionsList);
        if(CollectionUtils.isNotEmpty(staffs)){
            staffsString = JSONArray.toJSON(staffs).toString();
        }
        return staffsString;
    }

    @ApiOperation(value = "获得所有列表数据")
    @PostMapping(value = {"/getStaff"})
    public String getStaff(@RequestParam("staffCode")  String staffCode){
        String staffString = null;
        Staff staff =  staffService.get(staffCode);
        if(staff != null){
            staffString = JSONObject.toJSON(staff).toString();
        }
        return staffString;
    }

    @ApiOperation(value = "获得所有列表数据")
    @PostMapping(value = {"/selectStaffs"})
    public String selectStaffs(@RequestParam("filters") String filters){
        List<Filter> filterList = new ArrayList<>();
        if(StringUtils.isNotBlank(filters)){
            filterList = JSONArray.parseArray(filters, Filter.class);
        }
        String staffsString = null;
        List<Staff> staffs = staffService.select(filterList);
        if(CollectionUtils.isNotEmpty(staffs)){
            staffsString = JSONArray.toJSON(staffs).toString();
        }
        return staffsString;
    }

    @ApiOperation(value = "获得所有列表数据")
    @PostMapping(value = {"/get"})
    public Staff get(@RequestParam("staffCode")  String staffCode){
        return staffService.get(staffCode);
    }

    @ApiOperation(value = "获得所有列表数据")
    @PostMapping(value = {"/select"})
    public List<Staff> select(@RequestParam("filters") String filters){
        List<Filter> filterList = new ArrayList<>();
        if(StringUtils.isNotBlank(filters)){
            filterList = JSONArray.parseArray(filters, Filter.class);
        }
        return staffService.select(filterList);
    }

    @ApiOperation(value = "获取部门菜单信息")
    @GetMapping("/load")
    public List<UnitDto> loadUnit() {
        List<Unit> units = unitService.selectAll();
        List<UnitDto> unitDtos = new ArrayList<UnitDto>();
        for (Unit unit : units) {
            UnitDto unitDto = new UnitDto();
            unitDto.setId(unit.getUnitCode());
            unitDto.setTitle(unit.getName());
            unitDto.setParentId(unit.getParentId());
            unitDtos.add(unitDto);
        }
        return generateUnitDto(null, unitDtos);
    }

    private List<UnitDto> generateUnitDto(UnitDto parent, List<UnitDto> unitDtos) {
        List<UnitDto> data = new ArrayList<UnitDto>();
        for (UnitDto unitDto : unitDtos) {
            if (parent != null && parent.getId().equals(unitDto.getParentId())) {
                unitDto.setChildren(generateUnitDto(unitDto, unitDtos));
                data.add(unitDto);
            } else if (parent == null && StringUtils.isBlank(unitDto.getParentId())) {
                unitDto.setChildren(generateUnitDto(unitDto, unitDtos));
                data.add(unitDto);
            }
        }
        return data;
    }


    @ApiOperation(value = "")
    @PostMapping(value = {"/selectStaffByDeptCodes"})
    public List<StaffDto> selectStaffByDeptCodes(@ApiParam("部门列表") @RequestBody UnitDto unitDto) {
        String deptCodes = getDeptCodes(unitDto);
        List<Staff> StaffList = staffService.selectStaffByStdRolesAndDept(deptCodes.substring(0, deptCodes.length() - 1), null);
        List<StaffDto> StaffDtoList = new ArrayList();
        for (Staff staff : StaffList) {
            StaffDto staffDto = new StaffDto();
            BeanUtils.copyProperties(staff,staffDto);
            String roleCode = combineRoleCode(staffDto.getStaffCode());
            staffDto.setRoleCode(roleCode);
            String roleName = combineRoleName(staffDto.getStaffCode());
            staffDto.setRoleName(roleName);
            String roleGroupCode = combineRoleGroupCode(staffDto.getStaffCode());
            staffDto.setRoleGroupCode(roleGroupCode);
            String roleGroupName = combineRoleGroupName(staffDto.getStaffCode());
            staffDto.setRoleGroupName(roleGroupName);
            String staffGroupCode = combineStaffGroupCode(staff.getStaffCode());
            staffDto.setStaffGroupCode(staffGroupCode);
            String staffGroupName = combineStaffGroupName(staff.getStaffCode());
            staffDto.setStaffGroupName(staffGroupName);
            StaffDtoList.add(staffDto);
        }
        return StaffDtoList;
    }
    private String getDeptCodes(UnitDto unitDto) {
        String deptCodes = "";
        if (unitDto != null) {
            deptCodes += unitDto.getId() + ",";
            if (unitDto.getChildren() != null) {
                List<UnitDto> unitChilList = unitDto.getChildren();
                for (UnitDto unitDtoChil : unitChilList) {
                    deptCodes += getDeptCodes(unitDtoChil);
                }
            }
        }
        return deptCodes;
    }

    /**
     * 组装该用户所在的用户组名称
     *
     * @param staffCode 当前用户编码
     * @return
     */
    protected String combineStaffGroupName(String staffCode) {
        String staffGroupName = "";

        List<Filter> filters = new ArrayList<Filter>();
        filters.add(new Filter("staffCode", staffCode));
        List<StaffGroupMap> list = staffGroupMapService.select(filters);

        if (CollectionUtils.isNotEmpty(list)) {
            for (StaffGroupMap staffGroupMap : list) {
                String name = staffGroupService.get(staffGroupMap.getStaffGroupCode()).getStaffGroupName();
                staffGroupName += name + ",";
            }
            staffGroupName = staffGroupName.substring(0, staffGroupName.length() - 1);
        }

        return staffGroupName;
    }

    /**
     * 组装该用户所在的用户组编码
     *
     * @param staffCode 当前用户编码
     * @return
     */
    protected String combineStaffGroupCode(String staffCode) {
        String staffGroupCode = "";

        List<Filter> filters = new ArrayList<Filter>();
        filters.add(new Filter("staffCode", staffCode));
        List<StaffGroupMap> list = staffGroupMapService.select(filters);

        if (CollectionUtils.isNotEmpty(list)) {
            for (StaffGroupMap staffGroupMap : list) {
                String code = staffGroupMap.getStaffGroupCode();
                staffGroupCode += code + ",";
            }
            staffGroupCode = staffGroupCode.substring(0, staffGroupCode.length() - 1);
        }

        return staffGroupCode;
    }

    /**
     * 组装该用户所拥有的角色编码
     *
     * @param staffCode 当前用户编码
     * @return 角色名称组
     */
    protected String combineRoleCode(String staffCode) {
        String roleCode = "";

        List<Role> rolelist = dutyService.getStaffRoleList(staffCode, null);
        if (CollectionUtils.isNotEmpty(rolelist)) {
            for (Role role : rolelist) {
                roleCode += role.getRoleCode() + ",";
            }
            roleCode = roleCode.substring(0, roleCode.length() - 1);
        }

        return roleCode;
    }
    /**
     * 组装该用户所拥有的角色名称
     *
     * @param staffCode 当前用户编码
     * @return 角色名称组
     */
    protected String combineRoleName(String staffCode) {
        String roleName = "";

        List<Role> rolelist = dutyService.getStaffRoleList(staffCode, null);
        if (CollectionUtils.isNotEmpty(rolelist)) {
            for (Role role : rolelist) {
                roleName += role.getRoleName() + ", ";
            }
            roleName = roleName.substring(0, roleName.length() - 2);
        }

        return roleName;
    }

    /**
     * 组装该用户所拥有的角色组编码
     *
     * @param staffCode 当前用户编码
     * @return 角色名称组
     */
    protected String combineRoleGroupCode(String staffCode) {
        String roleGroupCode = "";
        List<RoleGroup> roleGroupList = staffRoleGroupMapService.getStaffRoleGroupList(staffCode);
        if (CollectionUtils.isNotEmpty(roleGroupList)) {
            for (RoleGroup roleGroup : roleGroupList) {
                roleGroupCode += roleGroup.getRoleGroupCode() + ",";
            }
            roleGroupCode = roleGroupCode.substring(0, roleGroupCode.length() - 1);
        }
        return roleGroupCode;
    }
    /**
     * 组装该用户所拥有的角色组名称
     *
     * @param staffCode 当前用户编码
     * @return 角色名称组
     */
    protected String combineRoleGroupName(String staffCode) {
        String roleGroupName = "";
        List<RoleGroup> roleGroupList = staffRoleGroupMapService.getStaffRoleGroupList(staffCode);
        if (CollectionUtils.isNotEmpty(roleGroupList)) {
            for (RoleGroup roleGroup : roleGroupList) {
                roleGroupName += roleGroup.getRoleGroupName() + ",";
            }
            roleGroupName = roleGroupName.substring(0, roleGroupName.length() - 1);
        }
        return roleGroupName;
    }
    @ApiOperation(value = "新增或者修改用户信息")
    @PostMapping(value = "/save")
    public Map<String, Object> save(@RequestBody StaffDto staff) {
        Map<String, Object> tips = new HashMap<String, Object>();
        try {
            Boolean isExist = staffService.exists(staff.getStaffCode());
            if (isExist) {
                staffService.updateStaff(staff);
            } else {
                userLoginService.saveStaff(staff);
            }
            tips.put(WebCode.SUCCESS, true);
            tips.put(WebCode.MSG, WebCode.SUCCESS_SAVE);
        } catch (Exception e) {
            LOG.info(e.getMessage());
            tips.put(WebCode.SUCCESS, false);
            tips.put(WebCode.MSG, WebCode.FAILURE_SAVE);
        }
        return tips;
    }

    @ApiOperation(value = "根据人员编号删除人员信息")
    @DeleteMapping(value = "/remove/{staffCode}")
    public Map<String, Object> remove(@PathVariable String staffCode) {
        Map<String, Object> tips = new HashMap<String, Object>();
        try {
            staffService.deleteStaff(staffCode);
            tips.put(WebCode.SUCCESS, true);
            tips.put(WebCode.MSG, WebCode.SUCCESS_DELETE);
        } catch (Exception e) {
            LOG.info(e.getMessage());
            tips.put(WebCode.SUCCESS, false);
            tips.put(WebCode.MSG, WebCode.FAILURE_DELETE);
        }
        return tips;
    }

    @ApiOperation(value = "验证提交的用户编码是否已经存在数据库中")
    @GetMapping(value = "/check", produces = "application/json;charset=UTF-8")
    public Map<String, Object> check( String staffCode) {
        Map<String, Object> tips = new HashMap<String, Object>();
        Staff exist = staffService.get(staffCode);
        if (exist == null) {
            tips.put("valid", true);
        } else {
            tips.put("valid", false);
        }
        return tips;
    }


    /**
     * 根据以“,”分割的用户编码查询，对应的用户
     *
     * @param staffCodes
     * @return
     */
    @ApiOperation(value = "根据以“,”分割的用户编码查询，对应的用户")
    @RequestMapping(value = "/selectStaffByCodes/{staffCodes}")
    public List<NameValuePair> selectStaffByCodes(@PathVariable String staffCodes) {
        if (StringUtils.isBlank(staffCodes)) return null;
        List<Filter> filters = new ArrayList<>();
        filters.add(new Filter("staffCode", Operator.IN, staffCodes.split(",")));
        List<Staff> staffs = staffService.select(filters);
        List<NameValuePair> nameValuePairs = new ArrayList<>();
        for (Staff staff : staffs) {
            nameValuePairs.add(new BasicNameValuePair(staff.getStaffName(), staff.getStaffCode()));
        }
        return nameValuePairs;
    }

}
